Initial import
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 31 Jul 2002 22:55:08 +0000 (22:55 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 31 Jul 2002 22:55:08 +0000 (22:55 +0000)
30 files changed:
gpsbabel/COPYING [new file with mode: 0644]
gpsbabel/Makefile [new file with mode: 0644]
gpsbabel/README [new file with mode: 0644]
gpsbabel/README.contrib [new file with mode: 0644]
gpsbabel/csv.c [new file with mode: 0644]
gpsbabel/defs.h [new file with mode: 0644]
gpsbabel/geo.c [new file with mode: 0644]
gpsbabel/geocaching.loc [new file with mode: 0644]
gpsbabel/gpsman [new file with mode: 0644]
gpsbabel/gpsman.c [new file with mode: 0644]
gpsbabel/gpsman2 [new file with mode: 0644]
gpsbabel/gpsutil.c [new file with mode: 0644]
gpsbabel/gpx.c [new file with mode: 0644]
gpsbabel/magellan.h [new file with mode: 0644]
gpsbabel/magproto.c [new file with mode: 0644]
gpsbabel/main.c [new file with mode: 0644]
gpsbabel/mapsend.c [new file with mode: 0644]
gpsbabel/mapsend.h [new file with mode: 0644]
gpsbabel/mapsource.c [new file with mode: 0644]
gpsbabel/pcx.c [new file with mode: 0644]
gpsbabel/queue.c [new file with mode: 0644]
gpsbabel/queue.h [new file with mode: 0644]
gpsbabel/reference/gl.loc [new file with mode: 0644]
gpsbabel/reference/gu.wpt [new file with mode: 0644]
gpsbabel/route.c [new file with mode: 0644]
gpsbabel/testo [new file with mode: 0755]
gpsbabel/tiger.c [new file with mode: 0644]
gpsbabel/util.c [new file with mode: 0644]
gpsbabel/vecs.c [new file with mode: 0644]
gpsbabel/waypt.c [new file with mode: 0644]

diff --git a/gpsbabel/COPYING b/gpsbabel/COPYING
new file mode 100644 (file)
index 0000000..514d6c7
--- /dev/null
@@ -0,0 +1,339 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          59 Temple Place - Suite 330, Boston, MA 02111 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+       Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/gpsbabel/Makefile b/gpsbabel/Makefile
new file mode 100644 (file)
index 0000000..094ff43
--- /dev/null
@@ -0,0 +1,15 @@
+CFLAGS=-g
+
+FMTS=magproto.o gpx.o geo.o gpsman.o mapsend.o mapsource.o \
+       gpsutil.o tiger.o pcx.o csv.o
+
+OBJS=main.o queue.o route.o waypt.o util.o vecs.o $(FMTS)
+
+gpsbabel: $(OBJS)
+       $(CC) $(CFLAGS) $(OBJS) -o gpsbabel -lexpat -lm
+
+clean:
+       rm -f $(OBJS) gpsbabel
+
+mapsend.o: mapsend.h
+magproto.o: magellan.h
diff --git a/gpsbabel/README b/gpsbabel/README
new file mode 100644 (file)
index 0000000..7856d7c
--- /dev/null
@@ -0,0 +1,115 @@
+
+THE PROBLEM
+
+       There are simply too many gratituosuly different file formats to 
+       hold waypoint and route information in various programs used by 
+       computers.  GPX (http://www.topografix.com/gpx.asp) attempts to 
+       define a standard in XML to contain all the data, but there are 
+       too many programs that don't understand it yet and too much data 
+       that are in an alternate format.
+
+THE SOLUTION
+
+       I needed to convert waypoints between a couple of formats, so
+       I whipped up a converter and based it on an extensible foundation
+       so that it was easy to add new formats.  Most file formats added
+       so far have taken under 200 lines of reasonable ISO C so they can
+       be stamped out pretty trivially. 
+
+THE FORMATS
+
+    GPX 
+
+       This is the most capable and expressive of all the file formats
+       supplied.    It is described at http://www.topografix.com/gpx.asp
+       and is supported by EasyGPS, ExpertGPS, and man other programs
+       described at http://www.topografix.com/gpx_resources.asp
+
+    GEO
+
+       geocaching.com spits up geocaching.loc files that are XML-ish but
+       not quite GPX.   Becuase it's so close to GPX, this format is very
+       well supported.
+
+    MAGELLAN
+
+       Waypoint upload and download works reliably.
+
+       As of this writing, there is still a lot of "scribbling" in the 
+       source for functionality that isn't hooked up to the rest of the
+       program.    Communication errors are handled and verification of
+       data is turned on.
+       
+    GPSMAN
+
+       GPS Manager can read and write formats that this converter doesn't
+       understand.  The default formats (WGS84, DDD) work reliably.
+
+    GPSUTIL
+
+       GPSUtil has a simple file format of this program that runs on POSIX-
+       compliant OSes like UNIX and Linux.   Reads and writes of this format
+       are reliable.   (I've also contributed to this program.)  It's  
+       available at http://www.cs.uakron.edu/~hennings/gpsutil/.
+
+    TIGER
+
+       The U.S. Census Bureau proives online mapping facilities.  This
+       format is described at: http://tiger.census.gov/instruct.html.
+
+    CSV
+
+       There are a billion variants of Comma Separated Value data.  This
+       is the one that makes Delorme S&A Deluxe 9 happy.
+
+    MAPSEND
+
+       Magellan was smart enough to document their file format to make
+       creating software like this possible.   It reads and writes only 
+       waypoints (not routes) at this time.
+
+    PCX
+
+       Garmin documents only PCX5, an older format limited to the lame NMEA
+       six-character waypoint names that's treated as a second-class citizien
+       in current versions of MapSource.  Use file->import to read these 
+       files.   Anyone with information on the *.mps file format that is
+       now preferred is encouraged to contact me with the details or better
+       yet, a module that implements it.   I spent time trying to reverse-
+       engineer a couple of *.mps files then I remembered that I don't own
+       a Garmin and wasn't that inspired.
+       
+
+COMMON USAGE
+
+       Invocation was meant to be flexible.   Unfortunately, that can
+       sometimes lead to unwieldy command lines.
+
+               mgps -? 
+
+       will always show you the supported file types.   To use this
+       program, just tell it what you're reading, where to read it from,
+       what you're writing, and what to write it to.  For example:
+
+       mgps -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx
+
+       tells it to read the first file in geocaching.com format and create
+       a new file in GPX format.
+
+
+ADVANCED USAGE
+
+       Argument are processed in the order they appear on the command line.
+       Input is cumulative.  The input file type remains unchanged until a 
+       new -i argument is seen.  Files are read in the order they appear.  
+       So you could merge three input files into one output file with:
+       
+       mgps -i geo 1.loc 2.loc 3.loc -o geo -F big.loc
+
+       You can merge files of different types:
+
+       mgps  -i geo 1.loc -i gpx 2.gpx -i pcx 3.pcx -o gpsutil -F big.gps
+
+       You can write the same data in different output formats:
+
+       mgps -i geo 1.loc -o gpx -F 1.gpx -o pcx 1.wpt
diff --git a/gpsbabel/README.contrib b/gpsbabel/README.contrib
new file mode 100644 (file)
index 0000000..e9028ea
--- /dev/null
@@ -0,0 +1,24 @@
+If you're interested in contributing to this program, here are some 
+guidelines.   Mail patches to robertlipe@usa.net for consideration and
+integration.
+
+Standards are good.   ISO C and POSIX are greal preferred.
+
+Reuse is OK, if not onerous.  For example, using the expat libraries vastly
+  simplifies the XML parsers while increasing their robustness plus those
+  libraries are ubiquitous.  So I consider it OK to require expat.
+
+If you contribute  a new target, contribute a test case along with it.  It's
+not that hard and it helps us be sure that the next version of thie program
+doesn't break your file format.
+
+Compilers complain for a reason.   Code shouldn't emit warnings.
+
+The entire world doesn't run <your OS here>.   I've tested this code on
+five different OSes.   If you find yourself wanting to insert compiler or
+OS specific magic, please resist.
+
+Enjoy!
+
+Robert Lipe,
+robertlipe@usa.net
diff --git a/gpsbabel/csv.c b/gpsbabel/csv.c
new file mode 100644 (file)
index 0000000..f97b208
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+  Comma separated value files.
+  NAME,LONG, LAT.
+  
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include <ctype.h>
+
+static FILE *file_in;
+static FILE *file_out;
+
+static void
+rd_init(const char *fname)
+{
+       file_in = fopen(fname, "r");
+       if (file_in == NULL) {
+               fatal("GPSUTIL: Cannot open %s for reading\n", fname);
+       }
+}
+
+static void
+rd_deinit(void)
+{
+       fclose(file_in);
+}
+
+static void
+wr_init(const char *fname)
+{
+       file_out = fopen(fname, "w");
+       if (file_out == NULL) {
+               fatal("GPSUTIL: Cannot open %s for writing\n", fname);
+       }
+}
+
+static void
+wr_deinit(void)
+{
+       fclose(file_out);
+}
+
+static void
+data_read(void)
+{
+       char name[9], desc[80];
+       char *odesc = desc;
+       double lat,lon;
+       char latdir, londir;
+       long alt; 
+       char alttype;
+       char icon[3] = {0};
+       waypoint *wpt_tmp;
+
+       while( fscanf(file_in, "%lf,%lf,%80[^\n]",
+                       &lat, &lon, desc) > 0) {
+               wpt_tmp = calloc(sizeof(*wpt_tmp),1);
+               if (wpt_tmp == NULL) {
+                       fatal("GPSMAN: cannot allocate memory\n");
+               }
+               while (*odesc == ' ' || *odesc == '\t') {
+                       odesc++;
+               }
+               wpt_tmp->shortname = strdup(odesc);
+               wpt_tmp->creation_time = time(NULL);
+
+               wpt_tmp->position.longitude.degrees = lon;
+               wpt_tmp->position.latitude.degrees = lat;
+
+               waypt_add(wpt_tmp);
+       }
+}
+
+static void
+gpsutil_disp(waypoint *wpt)
+{
+       double lon,lat;
+       signed int ilon, ilat;
+       const char *icon_token = "0";
+       char tbuf[1024];
+       char *tp = tbuf;
+       time_t tm = wpt->creation_time;
+
+       lon = wpt->position.longitude.degrees;
+       lat = wpt->position.latitude.degrees;
+
+       fprintf(file_out, "%08.5f, %08.5f, %s\n",
+               lat,
+               lon,
+               wpt->description);
+
+}
+
+static void
+data_write(void)
+{
+       waypt_disp_all(gpsutil_disp);
+}
+
+
+ff_vecs_t csv_vecs = {
+       rd_init,
+       wr_init,
+       rd_deinit,
+       wr_deinit,
+       data_read,
+       data_write,
+};
diff --git a/gpsbabel/defs.h b/gpsbabel/defs.h
new file mode 100644 (file)
index 0000000..77b03cc
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <time.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "queue.h"
+
+/*
+ * Common definitions.   There should be no protocol or file-specific
+ * data in this file.
+ */
+
+/*
+ * A coordinate in space.
+ */
+typedef struct {
+       double degrees;
+} coord;
+
+
+/*
+ * An altitude is essentially a coordinate along only the Z axis.
+ */
+
+typedef struct {
+       double altitude_meters;
+} altitude;
+
+
+/*
+ * A triplet of the coordinates along the three axes describes
+ * a position.
+ */
+typedef struct {
+       coord latitude;
+       coord longitude;
+       altitude altitude;
+} position;
+
+
+/*
+ * This is a waypoint, as stored in the GPSR.   It tries to not 
+ * cater to any specific model or protocol.  Anything that needs to
+ * be truncated, edited, or otherwise trimmed should be done on the
+ * way to the target.
+ */
+typedef struct {
+       queue Q;
+       position position;
+       time_t time_created; 
+       char *shortname;
+       char *description;
+       char *url;
+       char *url_link_text;
+       const char *icon_descr;
+       time_t creation_time;
+} waypoint;
+
+typedef void (*ff_init) (char const *);
+typedef void (*ff_deinit) (void);
+typedef void (*ff_read) (void);
+typedef void (*ff_write) (void);
+
+typedef void (*waypt_cb) (waypoint *);
+void waypt_add (waypoint *);
+void route_add (waypoint *);
+void waypt_disp_all(waypt_cb);
+unsigned int waypt_count(void);
+void fprintdms(FILE *, coord *, int);
+
+typedef struct ff_vecs {
+       ff_init rd_init;
+       ff_init wr_init;
+       ff_deinit rd_deinit;
+       ff_deinit wr_deinit;
+       ff_read read;
+       ff_write write;
+} ff_vecs_t;
+
+void waypt_init(void);
+void route_init(void);
+void waypt_disp(waypoint *);
+void fatal(const char *, ...);
+ff_vecs_t *find_vec(char *);
+
+void printposn(coord *c, int is_lat);
diff --git a/gpsbabel/geo.c b/gpsbabel/geo.c
new file mode 100644 (file)
index 0000000..5693aa4
--- /dev/null
@@ -0,0 +1,221 @@
+/* 
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <expat.h>
+#include "defs.h"
+
+static int in_wpt;
+static int in_name;
+static int in_link;
+
+static XML_Parser psr;
+static waypoint *wpt_tmp;
+
+FILE *fd;
+FILE *ofd;
+
+static void
+tag_coord(const char **attrv)
+{
+       const char **avp = &attrv[0];
+
+
+       while (*avp) { 
+               if (strcmp(avp[0], "lat") == 0) {
+                       sscanf(avp[1], "%lf", 
+                               &wpt_tmp->position.latitude.degrees);
+               }
+               else if (strcmp(avp[0], "lon") == 0) {
+                       sscanf(avp[1], "%lf", 
+                               &wpt_tmp->position.longitude.degrees);
+               }
+               avp+=2;
+       }
+}
+
+static void
+tag_name(const char **attrv)
+{
+       const char **avp = &attrv[0];
+       while (*avp) { 
+               if (strcmp(avp[0], "id") == 0) {
+                       wpt_tmp->shortname = strdup(avp[1]);
+               }
+               avp+=2;
+       }
+}
+
+static void
+tag_link(const char **attrv)
+{
+       const char **avp = &attrv[0];
+       while (*avp) { 
+               if (strcmp(avp[0], "text") == 0) {
+                       wpt_tmp->url_link_text = strdup(avp[1]);
+               }
+               avp+=2;
+       }
+}
+
+static void
+geo_start(void *data, const char *el, const char **attr)
+{
+
+       if (in_wpt) {
+               if (strcmp(el, "ele") == 0) {
+                       wpt_tmp->position.altitude.altitude_meters = atoi(attr[1]);
+               }
+               else if (strcmp(el, "name") == 0) {
+                       tag_name(attr);
+               }
+               else if (strcmp(el, "coord") == 0) {
+                       tag_coord(attr);
+               }
+       }
+
+       if (strcmp(el, "waypoint") == 0) {
+               wpt_tmp = calloc(sizeof(*wpt_tmp), 1);
+               in_wpt++;
+       } else if (strcmp(el, "name") == 0) {
+               in_name++;
+       } else if (strcmp(el, "link") == 0) {
+               tag_link(attr);
+               in_link++;
+       }
+}
+
+static void
+geo_end(void *data, const char *el)
+{
+       if (strcmp(el, "waypoint") == 0) {
+               waypt_add(wpt_tmp);
+               in_wpt--;
+       }
+       else if (strcmp(el, "name") == 0) {
+               in_name--;
+       }
+       else if (strcmp(el, "link") == 0) {
+               in_link--;
+       }
+}
+
+static void
+geo_cdata(void *dta, const XML_Char *s, int len)
+{
+       char *foo = malloc(len+1);
+       foo[len] = 0;
+       strncpy(foo, s, len);
+       if (in_name) {
+               wpt_tmp->description = foo;
+       }
+       if (in_link) {
+               wpt_tmp->url = foo;
+       }
+}
+
+
+void
+geo_rd_init(const char *fname)
+{
+       fd = fopen(fname, "r");
+       if (fd == NULL) {
+               abort();
+       }
+
+       psr = XML_ParserCreate(NULL);
+       if (!psr) {
+               abort();
+       }
+
+       XML_SetElementHandler(psr, geo_start, geo_end);
+       XML_SetCharacterDataHandler(psr, geo_cdata);
+}
+
+void
+geo_rd_deinit(void)
+{
+       fclose(fd);
+}
+
+void
+geo_wr_init(const char *fname)
+{
+       ofd = fopen(fname, "w");
+       if (ofd == NULL) {
+               abort();
+       }
+}
+
+void
+geo_wr_deinit(void)
+{
+       fclose(ofd);
+}
+
+void
+geo_read(void)
+{
+       int len;
+       char buf[1024];
+       
+       while ((len = fread(buf, 1, sizeof(buf), fd))) {
+               if (!XML_Parse(psr, buf, len, feof(fd))) {
+                       fprintf(stderr, "Parse error at %d: %s\n", 
+                               XML_GetCurrentLineNumber(psr),
+                               XML_ErrorString(XML_GetErrorCode(psr)));
+                       exit(1);
+               }
+       }
+       
+}
+
+static void
+geo_waypt_pr(waypoint *waypointp)
+{
+       fprintf(ofd, "<waypoint>\n");
+       fprintf(ofd, "<name id=\"%s\">", waypointp->shortname);
+       fprintf(ofd, "<![CDATA[%s]]>", waypointp->description);
+       fprintf(ofd, "</name>\n");
+
+       fprintf(ofd, "<coord lat=\"%lf\" lon=\"%lf\">",
+               waypointp->position.latitude.degrees,
+               waypointp->position.longitude.degrees);
+       fprintf(ofd, "</coord>\n");
+
+       fprintf(ofd, "<link text =\"Cache Details\">%s</link>\n", 
+               waypointp->url);
+       fprintf(ofd, "</waypoint>\n");
+}
+
+void
+geo_write(void)
+{
+       fprintf(ofd, "<?xml version=\"1.0\"?><loc version=\"1.0\" src=\"EasyGPS\">\n");
+       waypt_disp_all(geo_waypt_pr);
+       fprintf(ofd, "</loc>\n");
+}
+
+ff_vecs_t geo_vecs = {
+       geo_rd_init,    
+       geo_wr_init,    
+       geo_rd_deinit,
+       geo_wr_deinit,
+       geo_read,
+       geo_write,
+};
diff --git a/gpsbabel/geocaching.loc b/gpsbabel/geocaching.loc
new file mode 100644 (file)
index 0000000..4073f2c
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0"?><loc version="1.0" src="EasyGPS"><waypoint><name id="GCEBB"><![CDATA[Mountain Bike Heaven by susy1313]]></name><coord lat="35.9720333333333" lon="-87.1347"/><type>geocache</type><link text="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=3771</link></waypoint><waypoint><name id="GC1A37"><![CDATA[The Troll by a182pilot & Family]]></name><coord lat="36.0906833333333" lon="-86.67955"/><type>geocache</type><link text="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=6711</link></waypoint><waypoint><name id="GC1C2B"><![CDATA[Dive Bomber by JoGPS & family]]></name><coord lat="35.9962666666667" lon="-86.6201166666667"/><type>geocache</type><link text="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=7211</link></waypoint><waypoint><name id="GC25A9"><![CDATA[FOSTER by JoGPS & Family]]></name><coord lat="36.0384833333333" lon="-86.6486166666667"/><type>geocache</type><link text="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=9641</link></waypoint><waypoint><name id="GC2723"><![CDATA[Logan Lighthouse by JoGps & Family]]></name><coord lat="36.1121833333333" lon="-86.7417666666667"/><type>geocache</type><link text="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=10019</link></waypoint><waypoint><name id="GC2B71"><![CDATA[Ganier Cache by Susy1313]]></name><coord lat="36.0640833333333" lon="-86.7905166666667"/><type>geocache</type><link text="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=11121</link></waypoint><waypoint><name id="GC309F"><![CDATA[Shy's Hill by FireFighterEng33]]></name><coord lat="36.0877666666667" lon="-86.8097333333333"/><type>geocache</type><link text="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=12447</link></waypoint><waypoint><name id="GC317A"><![CDATA[GittyUp by JoGPS / Warner Parks]]></name><coord lat="36.0575" lon="-86.892"/><type>geocache</type><link text="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=12666</link></waypoint><waypoint><name id="GC317D"><![CDATA[Inlighting by JoGPS / Warner Parks]]></name><coord lat="36.0828" lon="-86.8672833333333"/><type>geocache</type><link text="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=12669</link></waypoint></loc>
\ No newline at end of file
diff --git a/gpsbabel/gpsman b/gpsbabel/gpsman
new file mode 100644 (file)
index 0000000..771a261
--- /dev/null
@@ -0,0 +1,53 @@
+% Written by GPSManager 05-Apr-2002 21:52:36 (EST)
+% Edit at your own risk!
+
+!Format: DMS 1 WGS 84
+!Creation: no
+
+!W:
+GC894          N41 20 07.9     W85 24 31.9     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC1F78         N40 43 04.1     W85 06 25.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+003            N41 07 21.3     W85 09 23.5     symbol=boat_ramp        alt=220.506469727       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC93           N41 43 09.4     W85 58 59.9     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2193         N40 25 29.0     W86 54 52.0     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+004            N41 07 22.6     W85 09 24.3     symbol=flag     alt=250.787719727       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GCA80          N40 29 14.3     W86 51 50.5     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC28CB         N40 50 32.8     W85 25 20.8     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2665         N40 45 56.4     W85 35 58.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+005            N41 02 51.4     W85 16 41.6     symbol=flag     alt=263.044433594       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GCB78          N40 26 17.9     W86 54 02.2     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2ADC         N40 26 16.4     W86 48 21.6     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+ABACUS         N41 04 20.6     W85 13 50.8     symbol=building alt=243.577880859       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GCD85          N41 05 03.3     W85 08 11.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GCB8           N40 26 09.5     W87 09 49.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2BE8         N40 52 45.9     W85 32 26.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+CASH1          N41 04 41.8     W85 08 19.3     symbol=flag     alt=245.740844727       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+H0ME           N41 02 51.7     W85 16 42.1     symbol=house    alt=272.176879883       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2C81         N41 12 24.2     W85 02 23.5     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+CENCEN         N41 41 39.0     W86 14 53.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+TOSB2          N41 44 00.4     W84 59 46.4     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2C90         N40 50 08.2     W85 27 14.9     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+CWORK          N41 07 23.0     W85 09 24.7     symbol=flag     alt=254.633056641       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+TOSB3          N41 43 21.9     W86 15 20.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2C91         N41 05 01.4     W85 08 18.7     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB1          N41 40 34.1     W86 15 01.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+UNITA          N41 02 52.2     W85 16 41.6     symbol=flag     alt=256.795898438       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2F53         N41 43 57.0     W86 04 48.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB2          N41 38 10.3     W86 15 04.4     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC333A         N41 01 42.7     W85 11 49.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB4          N41 37 27.7     W86 15 08.7     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB5          N41 38 53.4     W85 56 55.0     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC34D4         N41 58 16.8     W86 11 05.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB6          N41 34 46.3     W85 50 01.8     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC42A1         N41 05 02.1     W85 03 14.2     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC37C4         N41 38 15.5     W85 54 19.6     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB7          N41 07 42.2     W85 11 47.8     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC4378         N40 53 27.2     W85 28 13.4     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC11EF         N40 01 45.3     W86 53 17.4     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC44E5         N41 01 03.7     W85 15 07.0     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC12FF         N41 33 23.9     W86 21 26.9     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC47A5         N40 25 15.3     W86 54 17.6     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC17E0         N41 52 01.5     W86 36 12.5     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC488D         N41 33 43.7     W85 50 18.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC1A9C         N41 06 36.2     W85 09 20.8     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+
diff --git a/gpsbabel/gpsman.c b/gpsbabel/gpsman.c
new file mode 100644 (file)
index 0000000..e115e7d
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+
+static FILE *in_file;
+static FILE *out_file;
+
+static void
+gpsman_rd_init(const char *fname)
+{
+       in_file = fopen(fname, "r");
+       if (in_file == NULL) {
+               fatal("GPSMAN: Cannot open %s for reading\n", fname);
+       }
+
+}
+static void
+gpsman_rd_deinit(void)
+{
+       fclose(in_file);
+}
+
+static void
+gpsman_wr_init(const char *fname)
+{
+       out_file = fopen(fname, "w");
+       if (out_file == NULL) {
+               fatal("GPSMAN: Cannot open %s for writing\n", fname);
+       }
+
+       fprintf(out_file, "!Format: DDD 1 WGS 84\n");
+}
+
+static void
+gpsman_wr_deinit(void)
+{
+       fclose(out_file);
+}
+
+static void
+gpsman_disp(waypoint *waypointp)
+{
+       fprintf(out_file, "%-8.8s\t%s\t", 
+               waypointp->shortname, waypointp->description);
+       fprintdms(out_file, &waypointp->position.latitude, 1);
+       fprintdms(out_file, &waypointp->position.longitude, 0);
+       fprintf(out_file,"\n");
+}
+
+static void
+gpsman_parse_cmd(const char *cmd)
+{
+       return;
+}
+
+static void
+gpsman_read(void)
+{
+       char latdir, londir;
+       double latf, lonf;
+       int lonm, latm;
+       double lat, lon;
+       char sname[20];
+       char descr[100];
+       char ibuf[100];
+       waypoint *wpt_tmp;
+
+       while( fgets(ibuf, sizeof(ibuf), in_file)) {
+               if (ibuf[0] == '%' || ibuf[0] == '\n' ) {
+                       continue;
+               }
+               if (ibuf[0] == '!') {
+                       gpsman_parse_cmd(&ibuf[1]);
+                       continue;
+               }
+
+               sscanf(ibuf, "%[^\t] %[^\t] %c%d %lf %c%d %lf",
+                       sname, descr, &latdir, &latm, &latf, &londir, &lonm, &lonf);
+
+               wpt_tmp = calloc(sizeof(*wpt_tmp),1);
+
+               if (wpt_tmp == NULL) {
+                       fatal("GPSMAN: Cannot allocate enough memory\n");
+               }
+
+               lat = latm + latf;
+               lon = lonm + lonf;
+
+               if (latdir == 'S') lat = -lat;
+               if (londir == 'W') lon = -lon;
+
+               wpt_tmp->position.longitude.degrees = lon;
+               wpt_tmp->position.latitude.degrees = lat;
+               wpt_tmp->shortname = strdup(sname);
+               wpt_tmp->description = strdup(descr);
+
+               waypt_add(wpt_tmp);
+       }
+}
+
+static void
+gpsman_write(void)
+{
+       fprintf(out_file, "!W:\n");
+       waypt_disp_all(gpsman_disp);
+}
+
+ff_vecs_t gpsman_vecs = {
+       gpsman_rd_init, 
+       gpsman_wr_init, 
+       gpsman_rd_deinit,
+       gpsman_wr_deinit,
+       gpsman_read,
+       gpsman_write,
+};
diff --git a/gpsbabel/gpsman2 b/gpsbabel/gpsman2
new file mode 100644 (file)
index 0000000..4cf6db8
--- /dev/null
@@ -0,0 +1,75 @@
+% Written by GPSManager 24-May-2002 13:51:04 (CST)
+% Edit at your own risk!
+
+!Format: DMM 1 WGS 84
+!Creation: no
+
+!W:
+!Position: DMS
+GC37C4         N41 38 15.5     W85 54 19.6     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+H0ME           N41 02 51.7     W85 16 42.1     symbol=house    alt=272.176879883       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC894          N41 20 07.9     W85 24 31.9     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB7          N41 07 42.2     W85 11 47.8     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2C81         N41 12 24.2     W85 02 23.5     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC1F78         N40 43 04.1     W85 06 25.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC4378         N40 53 27.2     W85 28 13.4     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+TOSB2          N41 44 00.4     W84 59 46.4     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+CENCEN         N41 41 39.0     W86 14 53.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+003            N41 07 21.3     W85 09 23.5     symbol=boat_ramp        alt=220.506469727       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC11EF         N40 01 45.3     W86 53 17.4     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2C90         N40 50 08.2     W85 27 14.9     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC93           N41 43 09.4     W85 58 59.9     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC12FF         N41 33 23.9     W86 21 26.9     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC44E5         N41 01 03.7     W85 15 07.0     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+CWORK          N41 07 23.0     W85 09 24.7     symbol=flag     alt=254.633056641       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2193         N40 25 29.0     W86 54 52.0     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC47A5         N40 25 15.3     W86 54 17.6     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+TOSB3          N41 43 21.9     W86 15 20.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+004            N41 07 22.6     W85 09 24.3     symbol=flag     alt=250.787719727       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC17E0         N41 52 01.5     W86 36 12.5     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2C91         N41 05 01.4     W85 08 18.7     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GCA80          N40 29 14.3     W86 51 50.5     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC488D         N41 33 43.7     W85 50 18.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB1          N41 40 34.1     W86 15 01.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC28CB         N40 50 32.8     W85 25 20.8     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC1A9C         N41 06 36.2     W85 09 20.8     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+UNITA          N41 02 52.2     W85 16 41.6     symbol=flag     alt=256.795898438       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2665         N40 45 56.4     W85 35 58.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2F53         N41 43 57.0     W86 04 48.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+005            N41 02 51.4     W85 16 41.6     symbol=flag     alt=263.044433594       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GCB78          N40 26 17.9     W86 54 02.2     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB2          N41 38 10.3     W86 15 04.4     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2ADC         N40 26 16.4     W86 48 21.6     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB4          N41 37 27.7     W86 15 08.7     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC333A         N41 01 42.7     W85 11 49.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+ABACUS         N41 04 20.6     W85 13 50.8     symbol=building alt=243.577880859       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB5          N41 38 53.4     W85 56 55.0     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GCD85          N41 05 03.3     W85 08 11.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC34D4         N41 58 16.8     W86 11 05.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GCB8           N40 26 09.5     W87 09 49.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB6          N41 34 46.3     W85 50 01.8     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC2BE8         N40 52 45.9     W85 32 26.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC42A1         N41 05 02.1     W85 03 14.2     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+CASH1          N41 04 41.8     W85 08 19.3     symbol=flag     alt=245.740844727       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+
+!Position: DMM
+!R:    34      
+!Position: DMS
+003            N41 07 21.3     W85 09 23.5     symbol=boat_ramp        alt=220.506469727       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+004            N41 07 22.6     W85 09 24.3     symbol=flag     alt=250.787719727       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+005            N41 02 51.4     W85 16 41.6     symbol=flag     alt=263.044433594       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+ABACUS         N41 04 20.6     W85 13 50.8     symbol=building alt=243.577880859       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+CASH1          N41 04 41.8     W85 08 19.3     symbol=flag     alt=245.740844727       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+CENCEN         N41 41 39.0     W86 14 53.3     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+CWORK          N41 07 23.0     W85 09 24.7     symbol=flag     alt=254.633056641       GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+FRSB1          N41 40 34.1     W86 15 01.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC11EF         N40 01 45.3     W86 53 17.4     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GCD85          N41 05 03.3     W85 08 11.1     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+
+!R:    23      Route 23
+!NB:   blah blah blah
+
+GC11EF         N40 01 45.3     W86 53 17.4     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC12FF         N41 33 23.9     W86 21 26.9     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+GC1A9C         N41 06 36.2     W85 09 20.8     alt=-0.114379882812     GD108:class=|c! GD108:colour=~|Z        GD108:attrs=`   GD108:depth=QY|c%|_i    GD108:state=|cAA        GD108:country=|cAA
+
diff --git a/gpsbabel/gpsutil.c b/gpsbabel/gpsutil.c
new file mode 100644 (file)
index 0000000..8e1dcf0
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * written by robertlipe@usa.net
+ */
+
+#include "defs.h"
+#include "magellan.h"
+
+static FILE *file_in;
+static FILE *file_out;
+
+static void
+rd_init(const char *fname)
+{
+       file_in = fopen(fname, "r");
+       if (file_in == NULL) {
+               fatal("GPSUTIL: Cannot open %s for reading\n", fname);
+       }
+}
+
+static void
+rd_deinit(void)
+{
+       fclose(file_in);
+}
+
+static void
+wr_init(const char *fname)
+{
+       file_out = fopen(fname, "w");
+       if (file_out == NULL) {
+               fatal("GPSUTIL: Cannot open %s for writing\n", fname);
+       }
+}
+
+static void
+wr_deinit(void)
+{
+       fclose(file_out);
+}
+
+static void
+data_read(void)
+{
+       char name[9], desc[30];
+       double lat,lon;
+       char latdir, londir;
+       long alt; 
+       char alttype;
+       char icon[3] = {0};
+       waypoint *wpt_tmp;
+
+       while( fscanf(file_in, "%s %le%c %le%c %ld%c %30[^,] %c",
+                       name, &lat, &latdir, &lon, &londir,
+                       &alt, &alttype, desc, icon) > 0) {
+               wpt_tmp = calloc(sizeof(*wpt_tmp),1);
+               if (wpt_tmp == NULL) {
+                       fatal("GPSMAN: cannot allocate memory\n");
+               }
+               wpt_tmp->position.altitude.altitude_meters = alt;
+               wpt_tmp->shortname = strdup(name);
+               wpt_tmp->description = strdup(desc);
+               wpt_tmp->creation_time = time(NULL);
+
+               if (latdir == 'S') lat = -lat;
+               if (londir == 'W') lon = -lon;
+               wpt_tmp->position.longitude.degrees = lon/100.0;
+               wpt_tmp->position.latitude.degrees = lat/100.0;
+               wpt_tmp->icon_descr = strdup(icon);
+
+               waypt_add(wpt_tmp);
+       }
+}
+
+static void
+gpsutil_disp(waypoint *wpt)
+{
+       double lon,lat;
+       const char *icon_token;
+
+       icon_token = mag_find_token_from_descr(wpt->icon_descr);
+
+       lon = wpt->position.longitude.degrees * 100.0;
+       lat = wpt->position.latitude.degrees * 100.0;
+
+       fprintf(file_out, "%-8s %08.3f%c %09.3f%c %07.0f%c %-30.30s %s\n",
+               wpt->shortname,
+               fabs(lat),
+               lat < 0.0 ? 'S' : 'N',
+               fabs(lon),
+               lon < 0.0 ? 'W' : 'E',
+               wpt->position.altitude.altitude_meters,
+               'm', 
+               wpt->description,
+               icon_token);
+}
+
+static void
+data_write(void)
+{
+       waypt_disp_all(gpsutil_disp);
+}
+
+
+ff_vecs_t gpsutil_vecs = {
+       rd_init,
+       wr_init,
+       rd_deinit,
+       wr_deinit,
+       data_read,
+       data_write,
+};
diff --git a/gpsbabel/gpx.c b/gpsbabel/gpx.c
new file mode 100644 (file)
index 0000000..743fe86
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+    Access GPX data files.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <expat.h>
+#include "defs.h"
+
+static int in_wpt;
+static int in_rte;
+static int in_ele;
+static int in_name;
+static int in_time;
+static int in_desc;
+
+static XML_Parser psr;
+
+static const char *gpx_version;
+static const char *gpx_creator;
+
+static waypoint *wpt_tmp;
+static FILE *fd;
+static FILE *ofd;
+
+static void
+tag_gpx(const char **attrv)
+{
+       const char **avp = &attrv[0];
+       while (*avp) {
+               if (strcmp(avp[0], "version") == 0) {
+                       gpx_version = avp[1];
+               }
+               else if (strcmp(avp[0], "src") == 0) {
+                       gpx_creator = avp[1];
+               }
+               avp+=2;
+       }
+}
+
+static void
+tag_wpt(const char **attrv)
+{
+       const char **avp = &attrv[0];
+
+       wpt_tmp = calloc(sizeof(*wpt_tmp), 1);
+       if (wpt_tmp == NULL) {
+               fatal("Can not allocate memory\n");
+       }
+
+       while (*avp) { 
+               if (strcmp(avp[0], "lat") == 0) {
+                       sscanf(avp[1], "%lf", 
+                               &wpt_tmp->position.latitude.degrees);
+               }
+               else if (strcmp(avp[0], "lon") == 0) {
+                       sscanf(avp[1], "%lf", 
+                               &wpt_tmp->position.longitude.degrees);
+               }
+               avp+=2;
+       }
+}
+
+static void
+gpx_start(void *data, const char *el, const char **attr)
+{
+
+       if (strcmp(el, "ele") == 0) {
+               in_ele++;
+       } if (strcmp(el, "name") == 0) {
+               in_name ++;
+       } if (strcmp(el, "gpx") == 0) {
+               tag_gpx(attr);
+       } if (strcmp(el, "wpt") == 0) {
+               in_wpt++;
+               tag_wpt(attr);
+       } if (strcmp(el, "desc") == 0) {
+               in_desc++;
+       } if (strcmp(el, "rtept") == 0) {
+               in_rte++;
+               tag_wpt(attr);
+       } if (strcmp(el, "time") == 0) {
+               in_time++;
+       }
+}
+
+static void
+gpx_end(void *data, const char *el)
+{
+       if (strcmp(el, "wpt") == 0) {
+               waypt_add(wpt_tmp);
+               in_wpt--;
+       }
+       else if (strcmp(el, "rtept") == 0) {
+               route_add(wpt_tmp);
+               in_rte--;
+       } else if (strcmp(el, "name") == 0) {
+               in_name--;
+       } else if (strcmp(el, "desc") == 0) {
+               in_desc--;
+       } else if (strcmp(el, "ele") == 0) {
+               in_ele--;
+       } else if (strcmp(el, "time") == 0) {
+               in_time--;
+       }
+}
+
+static void
+gpx_cdata(void *dta, const XML_Char *s, int len)
+{
+       char *foo = malloc(len+1);
+       foo[len] = 0;
+       strncpy(foo, s, len);
+       if (in_name && in_wpt) {
+               wpt_tmp->shortname = foo;
+       }
+       if (in_desc) {
+               wpt_tmp->description = foo;
+       }
+       if (in_ele) {
+               sscanf(foo, "%lf", 
+                       &wpt_tmp->position.altitude.altitude_meters);
+       }
+       if (in_time && (in_wpt || in_rte)) {
+               struct tm tm;
+               sscanf(foo, "%d-%d-%dT%d:%d:%dZ\n", 
+                       &tm.tm_year,
+                       &tm.tm_mon,
+                       &tm.tm_mday,
+                       &tm.tm_hour,
+                       &tm.tm_min,
+                       &tm.tm_sec);
+               tm.tm_mon -= 1;
+               tm.tm_year -= 1900;
+               tm.tm_isdst = 1;
+               wpt_tmp->creation_time = mktime(&tm);
+       }
+}
+
+void
+gpx_rd_init(const char *fname)
+{
+       fd = fopen(fname, "r");
+       if (fd == NULL) {
+               fatal("GPX: Cannot open %s for reading\n", fname );
+       }
+       psr = XML_ParserCreate(NULL);
+       if (!psr) {
+               fatal("GPX: Cannot create XML Parser\n");
+       }
+       XML_SetElementHandler(psr, gpx_start, gpx_end);
+       XML_SetCharacterDataHandler(psr, gpx_cdata);
+}
+
+static void
+gpx_rd_deinit(void)
+{
+       fclose(fd);
+}
+
+void
+gpx_wr_init(const char *fname)
+{
+       ofd = fopen(fname, "w");
+       if (ofd == NULL) {
+               fatal("GPX: Cannot open %s for writing\n", fname );
+       }
+}
+
+static void
+gpx_wr_deinit(void)
+{
+       fclose(ofd);
+}
+void
+gpx_read(void)
+{
+       int len;
+       int done = 0;
+       char buf[102400];
+
+       while (!done) {
+               len = fread(buf, 1, sizeof(buf), fd);
+               done = feof(fd); 
+               if (!XML_Parse(psr, buf, len, done)) {
+                       fatal("GPX: XML parse error at %d: %s\n", 
+                               XML_GetCurrentLineNumber(psr),
+                               XML_ErrorString(XML_GetErrorCode(psr)));
+               }
+       }
+}
+
+static void
+gpx_waypt_pr(waypoint *waypointp)
+{
+
+       fprintf(ofd, "<wpt lat=\"%lf\" lon=\"%lf\">\n",
+               waypointp->position.latitude.degrees,
+               waypointp->position.longitude.degrees);
+       fprintf(ofd, "<name>%s</name>\n", waypointp->shortname);
+       fprintf(ofd, "<desc>");
+       fprintf(ofd, "<![CDATA[%s]]>", waypointp->description);
+       fprintf(ofd, "</desc>\n");
+       if (waypointp->position.altitude.altitude_meters) {
+               fprintf(ofd, "<ele>\n%f\n</ele>\n",
+                        waypointp->position.altitude.altitude_meters);
+       }
+       if (waypointp->url) {
+               fprintf(ofd, "<url>%s</url>\n", waypointp->url);
+       }
+       if (waypointp->url_link_text) {
+               fprintf(ofd, "<urlname>%s</urlname>\n",
+                        waypointp->url_link_text);
+       }
+       fprintf(ofd, "</wpt>\n");
+}
+
+void
+gpx_write(void)
+{
+       fprintf(ofd, "<?xml version=\"1.0\"?>\n");
+       fprintf(ofd, "<gpx\n\tversion=\"1.0\">\n");
+       waypt_disp_all(gpx_waypt_pr);
+       fprintf(ofd, "</gpx>\n");
+}
+
+ff_vecs_t gpx_vecs = {
+       gpx_rd_init,    
+       gpx_wr_init,    
+       gpx_rd_deinit,  
+       gpx_wr_deinit,  
+       gpx_read,
+       gpx_write,
+};
diff --git a/gpsbabel/magellan.h b/gpsbabel/magellan.h
new file mode 100644 (file)
index 0000000..b1d384b
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+/*
+ * Table of "interesting" Magellan models.
+ * Selfishly, if I haven't heard of it, it's not in the table.
+ * This doesn't mean I actually have TRIED all models listed below.
+ * (Donations welcome. :-)
+ */
+typedef enum {
+       mm_unknown,
+       mm_gps315320,
+       mm_map410,
+       mm_map330,
+       mm_gps310,
+       mm_meridian
+} meridian_model;
+
+typedef struct pid_to_model {
+       meridian_model model;
+       int pid;
+       const char *model_n;
+} pid_to_model_t;
+
+typedef struct icon_mapping {
+       const char *token;
+       const char *icon;
+} icon_mapping_t;
+
+const char * mag_find_descr_from_token(const char *token);
+const char * mag_find_token_from_descr(const char *icon);
diff --git a/gpsbabel/magproto.c b/gpsbabel/magproto.c
new file mode 100644 (file)
index 0000000..e23cdba
--- /dev/null
@@ -0,0 +1,585 @@
+/*
+    Communicate Thales/Magellan serial protocol.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <termios.h>
+#include <ctype.h>
+
+#include "defs.h"
+#include "magellan.h"
+
+#define debug 1
+
+typedef enum {
+       mrs_handoff = 0,
+       mrs_handon
+} mag_rxstate;
+
+static FILE *magfile;
+static int magfd;
+static mag_rxstate magrxstate;
+static struct termios orig_tio;
+static int last_rx_csum;
+static int found_done;
+static icon_mapping_t *icon_mapping;
+
+static waypoint * mag_wptparse(char *);
+
+static icon_mapping_t gps315_icon_table[] = {
+       { "a", "filled circle" },
+       { "b", "box" },
+       { "c", "red buoy" },
+       { "d", "green buoy" },
+       { "e", "buoy" },
+       { "f", "rocks" },
+       { "g", "red daymark" },
+       { "h", "green daymark" },
+       { "i", "bell" },
+       { "j", "danger" },
+       { "k", "diver down" },
+       { "l", "fish" },
+       { "m", "house" },
+       { "n", "mark" },
+       { "o", "car" },
+       { "p", "tent" },
+       { "q", "boat" },
+       { "r", "food" },
+       { "s", "fuel" },
+       { "t", "tree" },
+       { NULL, NULL }
+};
+
+static icon_mapping_t map330_icon_table[] = {
+       { "a", "crossed square" },
+       { "b", "box" },
+       { "c", "house" },
+       { "d", "aerial" },
+       { "e", "airport" },
+       { "f", "amusement park" },
+       { "g", "ATM" },
+       { "h", "auto repair" },
+       { "i", "boating" },
+       { "j", "camping" },
+       { "k", "exit ramp" },
+       { "l", "first aid" },
+       { "m", "nav aid" },
+       { "n", "buoy" },
+       { "o", "fuel" },
+       { "p", "garden" },
+       { "q", "golf" },
+       { "r", "hotel" },
+       { "s", "hunting/fishing" },
+       { "t", "large city" },
+       { "u", "lighthouse" },
+       { "v", "major city" },
+       { "w", "marina" },
+       { "x", "medium city" },
+       { "y", "museum" },
+       { "z", "obstruction" },
+       { "aa", "park" },
+       { "ab", "resort" },
+       { "ac", "restaraunt" },
+       { "ad", "rock" },
+       { "ae", "scuba" },
+       { "af", "RV service" },
+       { "ag", "shooting" },
+       { "ah", "sight seeing" },
+       { "ai", "small city" },
+       { "aj", "sounding" },
+       { "ak", "sports arena" },
+       { "al", "tourist info" },
+       { "am", "truck service" },
+       { "an", "winery" },
+       { "ao", "wreck" },
+       { "ap", "zoo" },
+       { NULL, NULL } 
+};
+
+pid_to_model_t pid_to_model[] = 
+{
+       { mm_gps315320, 24, "GPS 315/320" },
+       { mm_map410, 25, "Map 410" },
+       { mm_map330, 30, "Map 330" },
+       { mm_gps310, 31, "GPS 310" },
+       { mm_meridian, 33, "Meridian" },
+       { 0, 0, NULL }
+};
+
+
+/*
+ * Given a protocol message, compute the checksum as needed by 
+ * the Magellan protocol.
+ */
+static unsigned int 
+mag_checksum(const char * const buf)
+{
+       int csum = 0;
+       const char *p;
+
+       for(p = buf; *p; p++) {
+               csum  ^= *p;
+       }
+       
+       return csum;
+}
+static unsigned int
+mag_pchecksum(const char * const buf, int len)
+{
+       int csum = 0;
+       const char *p = buf;
+       for (; len ; len--) {
+               csum ^= *p++;
+       }
+       return csum;
+}
+
+static void
+mag_writemsg(const char * const buf)
+{
+       unsigned int osum = mag_checksum(buf);
+
+       if (debug) {
+               fprintf(stderr,"WRITE: $%s*%02X\r\n",buf, osum);
+       }
+#if 0
+       retry:
+#endif
+       fprintf(magfile, "$%s*%02X\r\n",buf, osum);
+#if 0
+       if (magrxstate == mrs_handon) {
+               mag_readmsg();
+               if (last_rx_csum != osum) {
+fprintf(stderr, "E");
+                       goto retry;
+               }
+       }
+#endif
+} 
+static void
+mag_writeack(int osum)
+{
+       char obuf[100];
+       snprintf(obuf, sizeof(obuf), "PMGNCSM,%02X", osum);
+       mag_writemsg(obuf);
+}
+
+static void
+mag_handon(void)
+{
+       magrxstate = mrs_handon;
+       mag_writemsg("PMGNCMD,HANDON");
+}
+
+static void
+mag_handoff(void)
+{
+       magrxstate = mrs_handoff;
+       mag_writemsg("PMGNCMD,HANDOFF");
+}
+
+void
+mag_verparse(char *ibuf)
+{
+       int prodid = mm_unknown; 
+       char version[1024];
+       pid_to_model_t *pp = pid_to_model;
+       sscanf(ibuf,"$PMGNVER,%d,%[^,]", &prodid, version);
+
+       for (pp = pid_to_model; pp->model ; pp++) {
+               if (pp->pid == prodid) {
+                       break;
+               }
+       }
+       switch (pp->model) {
+               case mm_gps315320:
+               case mm_map410:
+                       icon_mapping = gps315_icon_table;
+                       break;
+               case mm_map330:
+               case mm_meridian:
+                       icon_mapping = map330_icon_table;
+                       break;
+               default:
+                       abort();
+       }
+}
+
+#define IS_TKN(x) (strncmp(ibuf,x, sizeof(x)-1) == 0)
+
+static void
+mag_readmsg(void)
+{
+       char ibuf[100];
+       int isz;
+       unsigned int isum;
+       char *isump;
+       fgets(ibuf, sizeof(ibuf), magfile);
+       isz = strlen(ibuf);
+       if (isz < 5) {
+if (debug)
+fprintf(stderr, "SHORT READ %d\n", isz);
+               return;
+       }
+       while (!isprint(ibuf[isz]))
+               isz--;
+       isump = &ibuf[isz-1];
+       isum  = strtoul(isump, NULL,16); 
+       if (isum != mag_pchecksum(&ibuf[1], isz-3)) {
+if (debug)
+               fprintf(stderr, "RXERR %02x/%02x: '%s'\n", isum, mag_pchecksum(&ibuf[1],isz-5), ibuf);
+       }
+if (debug)
+fprintf(stderr, "READ: %s\n", ibuf);
+       if (IS_TKN("$PMGNCSM,")) {
+               last_rx_csum = strtoul(&ibuf[9], NULL, 16);
+               return;
+       } 
+       if (strncmp(ibuf, "$PMGNWPT,", 7) == 0) {
+               waypoint *wpt = mag_wptparse(ibuf);
+               waypt_add(wpt);
+       } 
+       if (IS_TKN("$PMGNVER,")) {
+               mag_verparse(ibuf);
+return;
+       } 
+       if (IS_TKN("$PMGNCMD,END")) {
+               found_done = 1;
+return;
+       } 
+       mag_writeack(isum);
+}
+
+static void
+mag_rd_init(const char *portname)
+{
+       struct termios new_tio;
+       magfile = fopen(portname, "rw+b");
+       
+       if (magfile == NULL) {
+               perror("Open failed");
+               return;
+       }
+
+       magfd = fileno(magfile);
+       tcgetattr(magfd, &orig_tio);
+       new_tio = orig_tio;
+       new_tio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|
+               IXON);
+       new_tio.c_oflag &= ~OPOST;
+       new_tio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+       new_tio.c_cflag &= ~(CSIZE|PARENB);
+       new_tio.c_cflag |= CS8;
+
+       cfsetospeed(&new_tio, B4800);
+       cfsetispeed(&new_tio, B4800);
+       tcsetattr(magfd, TCSAFLUSH, &new_tio);
+       
+       mag_handon();
+       mag_writemsg("PMGNCMD,VERSION");
+       mag_writemsg("PMGNCMD,NMEAOFF");
+       return;
+}
+
+static void
+mag_deinit(void)
+{
+       mag_handoff();
+       tcsetattr(magfd, TCSANOW, &orig_tio);
+       fclose(magfile);
+}
+
+/*
+ * Given an incoming track messages of the form:
+ * $PMGNTRK,3605.259,N,08644.389,W,00151,M,201444.61,A,,020302*66
+ * create and return a populated waypoint.
+ */
+waypoint * 
+mag_trkparse(char *trkmsg)
+{
+       double latdeg, lngdeg;
+       int alt;
+       char altunits;
+       char lngdir, latdir;
+       int dmy;
+       int hms;
+       int fracsecs;
+       struct tm tm;
+       waypoint *waypt;
+
+       waypt  = calloc(sizeof *waypt, 1);
+       if (waypt == NULL) 
+               return NULL;
+
+       printf("%s\n", trkmsg);
+       memset(&tm, 0, sizeof(tm));
+#if 0
+       sscanf(trkmsg,"$PMGNTRK,%lf,%c,%lf,%c,%d,%c,%d.%d,A,,%d", 
+               &latdeg,&latdir,
+               &lngdeg,&lngsecs,&lngdir,
+               &alt,&altunits,&hms,&fracsecs,&dmy);
+#else
+latdeg = 123;
+#endif
+
+       tm.tm_sec = hms % 100;
+       hms = hms / 100;
+       tm.tm_min = hms % 100;
+       hms = hms / 100;
+       tm.tm_hour = hms % 100;
+
+       tm.tm_mon =  dmy % 100;
+       dmy = dmy / 100;
+       tm.tm_mday = dmy % 100; 
+       dmy = dmy / 100;
+       tm.tm_year = 100 + dmy % 100;
+
+       /*
+        * FIXME: mktime assumes the struct tm is in local time, which 
+        * ours is not...
+        */
+       waypt->time_created = mktime(&tm);
+
+       waypt->position.latitude.degrees = latdeg / 100.0;
+       waypt->position.longitude.degrees = lngdeg / 100.0;
+       waypt->position.altitude.altitude_meters = alt;
+
+       return waypt;
+       
+}
+
+const char *
+mag_find_descr_from_token(const char *token)
+{
+       icon_mapping_t *i = icon_mapping;
+
+       if (icon_mapping == NULL) {
+               return "unknown";
+       }
+
+       for (i = icon_mapping; i->token; i++) {
+               if (strcmp(token, i->token) == 0)
+                       return i->icon;
+       }
+       return icon_mapping[0].icon;
+}
+
+const char *
+mag_find_token_from_descr(const char *icon)
+{
+       icon_mapping_t *i = icon_mapping;
+
+       if (i == NULL || icon == NULL) {
+               return "a";
+       }
+
+       for (i = icon_mapping; i->token; i++) {
+               if (strcmp(icon, i->icon) == 0)
+                       return i->token;
+       }
+       return icon_mapping[0].token;
+}
+
+
+/*
+ * Given an incoming waypoint messages of the form:
+ * $PMGNWPL,3549.499,N,08650.827,W,0000257,M,HOME,HOME,c*4D
+ * create and return a populated waypoint.
+ */
+waypoint * 
+mag_wptparse(char *trkmsg)
+{
+       double latdeg, lngdeg;
+       char latdir;
+       char lngdir;
+       int alt;
+       char altunits;
+       char shortname[100];
+       char descr[100];
+       char icon_token[100];
+       waypoint *waypt;
+       char *icons;
+       char *icone;
+       char *blah;
+       int i = 0;
+
+       descr[0] = 0;
+       icon_token[0] = 0;
+
+       waypt  = calloc(sizeof *waypt, 1);
+       if (waypt == NULL) 
+               fatal("Magproto: Cannot allocate memory\n");
+
+       sscanf(trkmsg,"$PMGNWPL,%lf,%c,%lf,%c,%d,%c,%[^,],%[^,]", 
+               &latdeg,&latdir,
+               &lngdeg,&lngdir,
+               &alt,&altunits,shortname,descr);
+       icone = strrchr(trkmsg, '*');
+       icons = strrchr(trkmsg, ',')+1;
+       
+       for (blah = icons ; blah < icone; blah++)
+               icon_token[i++] = *blah;
+
+       if (latdir == 'S') latdeg = -latdeg;
+       waypt->position.latitude.degrees = latdeg / 100.0;
+
+       if (lngdir == 'W') lngdeg = -lngdeg;
+       waypt->position.longitude.degrees = lngdeg / 100.0;
+
+       waypt->position.altitude.altitude_meters = alt;
+       waypt->shortname = strdup(shortname);
+       waypt->description = strdup(descr);
+       waypt->icon_descr = mag_find_descr_from_token(icon_token);
+
+       return waypt;
+}
+
+#if BLERF
+
+int main(void)
+{
+char trk1[] = "$PMGNTRK,3605.259,N,08644.389,W,00151,M,201444.61,A,,020302*66";
+char trk2[] = "$PMGNTRK,3605.315,N,08644.625,W,00153,M,211618.68,A,,020302*6D";
+char trk3[] = "$PMGNTRK,3605.320,N,08644.619,W,00164,M,212121.87,A,,020302*6F";
+char wpt1[] = "$PMGNWPL,3604.831,N,08659.737,W,0000000,M,PowerPln,Power Plant by White Dog Pack,a*50";
+char wpt2[] = "$PMGNWPL,3614.645,N,08641.885,W,0000000,M,CmbrlndR,Cumberland River Cache by GISG,a*7B";
+char wpt3[] = "$PMGNWPL,3608.210,N,08648.389,W,0000000,M,Puff!,Puff! by White Dog Pack,a*61";
+waypt_init();
+route_init();
+
+#if 1
+mag_trkparse(trk1);
+mag_trkparse(trk2);
+mag_trkparse(trk3);
+
+exit(0);
+#endif
+
+#if 1
+mag_wptparse(wpt1);
+mag_wptparse(wpt2);
+mag_wptparse(wpt3);
+exit(0);
+#endif
+       mag_init();
+
+#if 1
+       mag_writemsg("PMGNCMD,WAYPOINT");
+while (!found_done) {
+ mag_readmsg();
+}
+exit(0);
+#endif
+#if 0
+       mag_writemsg("PMGNCMD,TRACK,2");
+while (!found_done) {
+ mag_readmsg();
+}
+#endif
+#if 1
+       mag_writemsg("PMGNCMD,ROUTE");
+while (!found_done) {
+ mag_readmsg();
+}
+exit(0);
+#endif
+#if 0
+       mag_writemsg("PMGNCMD,FIL,FIRST,?");
+sleep(2);
+ mag_readmsg();
+while (!found_done) {
+  mag_writemsg("PMGNCMD,FIL,NEXT");
+ mag_readmsg();
+sleep(2);
+}
+#endif
+       mag_deinit();
+       return 0;
+}
+
+#if SOON
+/* ROUTES */
+READ: $PMGNRTE,3,1,c,19,HOME,c,KidsAtPl,a*0F
+READ: $PMGNRTE,3,2,c,19,TrainWrc,a,Leipers,a*6F
+READ: $PMGNRTE,3,3,c,19,Nashvill,a,HOME,c*1A
+
+/* WAYPOINTS */
+READ: $PMGNWPL,3604.831,N,08659.737,W,0000000,M,PowerPln,Power Plant by White Do
+READ: $PMGNWPL,3614.645,N,08641.885,W,0000000,M,CmbrlndR,Cumberland River Cache
+READ: $PMGNWPL,3608.210,N,08648.389,W,0000000,M,Puff!,Puff! by White Dog Pack,a*
+61
+
+#endif
+#endif
+
+void
+mag_readwpt(void)
+{
+       mag_writemsg("PMGNCMD,WAYPOINT");
+       while (!found_done) {
+               mag_readmsg();
+       }
+}
+
+static
+void
+mag_waypt_pr(waypoint *waypointp)
+{
+       double lon, lat;
+       double ilon, ilat;
+       char obuf[200];
+       ilat = waypointp->position.latitude.degrees;
+       ilon = waypointp->position.longitude.degrees;
+
+       lon =fabs(ilon * 100.0);
+       lat =fabs(ilat * 100.0);
+
+       sprintf(obuf, "PMGNWPL,%4.3f,%c,%05.3f,%c,%.lf,M,%-.8s,%-.20s,%s",
+               lat, ilon < 0 ? 'N' : 'S',
+               lon, ilat < 0 ? 'E' : 'W',
+               waypointp->position.altitude.altitude_meters,
+               waypointp->shortname,
+               waypointp->description,
+               waypointp->icon_descr);
+       mag_writemsg(obuf);
+       mag_readmsg();
+}
+
+
+void
+mag_write(void)
+{
+#if 1
+               mag_readmsg();
+               mag_readmsg();
+               mag_readmsg();
+               mag_readmsg();
+#endif
+       waypt_disp_all(mag_waypt_pr);
+       
+}
+
+ff_vecs_t mag_vecs = {
+       mag_rd_init,    
+       mag_rd_init,    
+       mag_deinit,     
+       mag_deinit,     
+       mag_readwpt,
+       mag_write,
+};
diff --git a/gpsbabel/main.c b/gpsbabel/main.c
new file mode 100644 (file)
index 0000000..c10b2c8
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+
+#include "defs.h"
+#include <unistd.h>
+
+void
+usage(const char *pname)
+{
+       printf("Usage: %s -i <INPUT_FILE_TYPE> -f <INPUT_FILE> -o <OUT FTYPE> -F <OUTPUT_FILE>\n", pname);
+       printf("Supported file types:\n");
+       disp_vecs();
+}
+
+int
+main(int argc, char *argv[])
+{
+       int c;
+       ff_vecs_t *ivecs = NULL;
+       ff_vecs_t *ovecs = NULL;
+       char *fname = NULL;
+       char *ofname = NULL;
+
+       waypt_init();
+       route_init();
+
+       while (( c = getopt(argc, argv, "?hi:o:f:F:")) != EOF) {
+               switch (c) {
+                       case 'i': 
+                               ivecs = find_vec(optarg);
+                               break;
+                       case 'o':
+                               ovecs = find_vec(optarg);
+                               break;
+                       case 'f':
+                               fname = optarg;
+                               if (ivecs == NULL) {
+                                       fatal ("No valid input type specified");
+                               }
+                               ivecs->rd_init(fname);
+                               ivecs->read();
+                               break;
+                       case 'F':
+                               ofname = optarg;
+                               if (ovecs) {
+                                       ovecs->wr_init(ofname);
+                                       ovecs->write();
+                               }
+                               break;
+                       case 'h':
+                       case '?':
+                               usage(argv[0]);
+                               exit(0);
+               }
+       }
+
+       if (ovecs == NULL)
+               waypt_disp_all(waypt_disp);
+
+       exit(0);
+}
diff --git a/gpsbabel/mapsend.c b/gpsbabel/mapsend.c
new file mode 100644 (file)
index 0000000..6a913da
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+    Access Magellan Mapsend files.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "defs.h"
+#include "mapsend.h"
+
+static FILE *mapsend_file_in;
+static FILE *mapsend_file_out;
+
+static void
+mapsend_rd_init(const char *fname)
+{
+       mapsend_file_in = fopen(fname, "r");
+       if (mapsend_file_in == NULL) {
+               fprintf(stderr, "Cannot open '%s' for reading\n", fname);
+               exit(1);
+       }
+}
+
+static void
+mapsend_rd_deinit(void)
+{
+       fclose(mapsend_file_in);
+}
+
+static void
+mapsend_wr_init(const char *fname)
+{
+       mapsend_file_out = fopen(fname, "w");
+       if (mapsend_file_out == NULL) {
+               fprintf(stderr, "Cannot open '%s' for writing\n", fname);
+               exit(1);
+       }
+}
+
+static void
+mapsend_wr_deinit(void)
+{
+       fclose(mapsend_file_out);
+}
+
+static void
+mapsend_read(void)
+{
+       mapsend_hdr hdr;
+       char tbuf[256];
+       char name[257];
+       char comment[257];
+       char *p;
+       int wpt_count;
+       unsigned char scount;
+       int wpt_number;
+       char wpt_icon;
+       char wpt_status;
+       double wpt_alt;
+       double wpt_long;
+       double wpt_lat;
+       waypoint *wpt_tmp;
+
+       /*
+        * Becuase of the silly struct packing and the goofy variable-length
+        * strings, each member has to be read in one at a time.  Grrr.
+        */
+
+       fread(&hdr, sizeof(hdr), 1, mapsend_file_in);
+
+       fread(&wpt_count, sizeof(wpt_count), 1, mapsend_file_in);
+
+       while (wpt_count--) {
+               wpt_tmp = calloc(sizeof(*wpt_tmp), 1);
+
+               fread(&scount, sizeof(scount), 1, mapsend_file_in);
+               fread(&tbuf, scount, 1, mapsend_file_in);
+               p = strncpy(name, tbuf, scount);
+               p[scount] = '\0';
+
+               fread(&scount, sizeof(scount), 1, mapsend_file_in);
+               fread(&tbuf, scount, 1, mapsend_file_in);
+               p = strncpy(comment, tbuf, scount);
+               p[scount] = '\0';
+
+               fread(&wpt_number, sizeof(wpt_number), 1, mapsend_file_in);
+               fread(&wpt_icon, sizeof(wpt_icon), 1, mapsend_file_in);
+               fread(&wpt_status, sizeof(wpt_status), 1, mapsend_file_in);
+               fread(&wpt_alt, sizeof(wpt_alt), 1, mapsend_file_in);
+               fread(&wpt_long, sizeof(wpt_long), 1, mapsend_file_in);
+               fread(&wpt_lat, sizeof(wpt_lat), 1, mapsend_file_in);
+
+               wpt_tmp->shortname = strdup(name);
+               wpt_tmp->description = strdup(comment);
+               wpt_tmp->position.altitude.altitude_meters = wpt_alt;
+               wpt_tmp->position.latitude.degrees = -wpt_lat;
+               wpt_tmp->position.longitude.degrees = wpt_long;
+
+               waypt_add(wpt_tmp);
+       }
+}
+
+static void
+mapsend_waypt_pr(waypoint *waypointp)
+{
+       int n;
+       double falt;
+       double flong;
+       double flat;
+static int cnt = 0;
+
+       n = strlen(waypointp->shortname);
+       fwrite(&n, 1, 1, mapsend_file_out);
+       fwrite(waypointp->shortname, n, 1, mapsend_file_out);
+
+       n = strlen(waypointp->description);
+       fwrite(&n, 1, 1, mapsend_file_out);
+       fwrite(waypointp->description, n, 1, mapsend_file_out);
+
+       /* #, icon, status */
+n = ++cnt;
+       fwrite(&n, 4, 1, mapsend_file_out);
+n = 0;
+       fwrite(&n, 1, 1, mapsend_file_out);
+n = 1;
+       fwrite(&n, 1, 1, mapsend_file_out);
+
+       falt = waypointp->position.altitude.altitude_meters;
+       fwrite(&falt, sizeof(double), 1, mapsend_file_out);
+
+       flong = waypointp->position.longitude.degrees;
+       fwrite(&flong, sizeof(double), 1, mapsend_file_out);
+       flat = -waypointp->position.latitude.degrees;
+       fwrite(&flat, sizeof(double), 1, mapsend_file_out);
+}
+
+void
+mapsend_write(void)
+{
+       mapsend_hdr hdr = {13, "4D533330 MS", "30", 1};
+       int wpt_count = waypt_count();
+int n = 0;
+
+       fwrite(&hdr, sizeof(hdr), 1, mapsend_file_out);
+       fwrite(&wpt_count, sizeof(wpt_count), 1, mapsend_file_out);
+
+       waypt_disp_all(mapsend_waypt_pr);
+
+       fwrite(&n, 4, 1, mapsend_file_out);
+/* TODO: Impelment routes here */
+}
+
+ff_vecs_t mapsend_vecs = {
+       mapsend_rd_init,
+       mapsend_wr_init,
+       mapsend_rd_deinit,
+       mapsend_wr_deinit,
+       mapsend_read,
+       mapsend_write,
+};
diff --git a/gpsbabel/mapsend.h b/gpsbabel/mapsend.h
new file mode 100644 (file)
index 0000000..2e617fc
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+    Access to MapSend files.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ *
+ * Information from:
+ *  Mapsend File Format Description Revision 1.1, March 6, 2002 from Thales.
+ * 
+ * Note this file format was clearly NOT designed for cross-architecture
+ * portability.  In fact, becuase of the pascal nature of the 'string' 
+ * data type described in that document, it's impractical to describe 
+ * a 'struct waypoint' in C.
+ * 
+ */
+
+typedef struct {
+       char ms_length;
+       char ms_signature[11];
+       char ms_version[2];
+       char ms_type;
+       char _ms_type[3];
+} mapsend_hdr;
diff --git a/gpsbabel/mapsource.c b/gpsbabel/mapsource.c
new file mode 100644 (file)
index 0000000..446da14
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+    Acess to Garmin MapSource files.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "defs.h"
+#include <ctype.h>
+
+static FILE *mapsource_file_in;
+static FILE *mapsource_file_out;
+
+static void
+mapsource_rd_init(const char *fname)
+{
+       mapsource_file_in = fopen(fname, "r");
+       if (mapsource_file_in == NULL) {
+               fprintf(stderr, "Cannot open '%s' for reading\n", fname);
+               exit(1);
+       }
+}
+
+static void
+mapsource_rd_deinit(void)
+{
+       fclose(mapsource_file_in);
+}
+
+static void
+mapsource_wr_init(const char *fname)
+{
+       mapsource_file_out = fopen(fname, "w");
+       if (mapsource_file_out == NULL) {
+               fprintf(stderr, "Cannot open '%s' for writing\n", fname);
+               exit(1);
+       }
+}
+
+static void
+mapsource_wr_deinit(void)
+{
+       fclose(mapsource_file_out);
+}
+
+static void
+mapsource_read(void)
+{
+       char name[9], date[20], timeb[20];
+       char ibuf[200];
+       double lat,lon;
+       char latdir, londir;
+       int latd, lond;
+       float latf, lonf;
+       int alt; 
+       char altunits[10];
+       char icon[20];
+       waypoint *wpt_tmp;
+
+       while (fgets(ibuf, sizeof(ibuf), mapsource_file_in)) {
+               sscanf(ibuf,
+               "Waypoint %s %s %s %c%d %f %c%d %f %d %s Symbol & Name %s",
+                name, date, timeb, &latdir, &latd, &latf, &londir, &lond, &lonf, &alt, altunits, icon);
+               wpt_tmp = calloc(sizeof(*wpt_tmp),1);
+               if (wpt_tmp == NULL) {
+                       fatal("MAPSOURCE: cannot allocate memory\n");
+               }
+/* FIXME: Implement actual appropriate conversion */
+               wpt_tmp->position.altitude.altitude_meters = alt * 3.0;
+               wpt_tmp->shortname = strdup(name);
+               wpt_tmp->description = strdup(name);
+
+               lat = latd + latf/100.0;
+               lon = lond + lonf/100.0;
+               if (latdir == 'S') lat = -lat;
+               if (londir == 'W') lon = -lon;
+               wpt_tmp->position.latitude.degrees = lat;
+               wpt_tmp->position.longitude.degrees = lon;
+
+               waypt_add(wpt_tmp);
+       }
+}
+
+static void
+mapsource_waypt_pr(waypoint *waypointp)
+{
+       char tbuf[1024];
+       char *tp = tbuf;
+       int d;
+       strftime(tbuf, sizeof(tbuf), "%d-%b-%y %I:%M:%S%p", localtime(&waypointp->creation_time));
+       while (*tp) {
+               *tp = toupper(*tp);
+               tp++;
+       }
+/* FIXME: cure the sign dependencies here. */
+       fprintf(mapsource_file_out, "Waypoint %s %s ", waypointp->shortname, tbuf);
+       fprintf(mapsource_file_out, "N%02.0f", waypointp->position.latitude.degrees);
+       d = waypointp->position.latitude.degrees;
+       fprintf(mapsource_file_out, " %06.3f ", (waypointp->position.latitude.degrees - d) * 100);
+       fprintf(mapsource_file_out, "W%02.0f", fabs(waypointp->position.longitude.degrees));
+       d = fabs(waypointp->position.longitude.degrees);
+       fprintf(mapsource_file_out, " %06.3f ", (fabs(waypointp->position.longitude.degrees) - d) * 100);
+       fprintf(mapsource_file_out, "0 ft Symbol & Name Unknown\n");
+}
+
+void
+mapsource_write(void)
+{
+       waypt_disp_all(mapsource_waypt_pr);
+
+}
+
+ff_vecs_t mapsource_vecs = {
+       mapsource_rd_init,
+       mapsource_wr_init,
+       mapsource_rd_deinit,
+       mapsource_wr_deinit,
+       mapsource_read,
+       mapsource_write,
+};
diff --git a/gpsbabel/pcx.c b/gpsbabel/pcx.c
new file mode 100644 (file)
index 0000000..f65b83e
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+    Access to Garmin PCX5 files.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+*/
+
+
+#include "defs.h"
+#include <ctype.h>
+
+static FILE *file_in;
+static FILE *file_out;
+
+static void
+rd_init(const char *fname)
+{
+       file_in = fopen(fname, "r");
+       if (file_in == NULL) {
+               fatal("GPSUTIL: Cannot open %s for reading\n", fname);
+       }
+}
+
+static void
+rd_deinit(void)
+{
+       fclose(file_in);
+}
+
+static void
+wr_init(const char *fname)
+{
+       file_out = fopen(fname, "w");
+       if (file_out == NULL) {
+               fatal("GPSUTIL: Cannot open %s for writing\n", fname);
+       }
+}
+
+static void
+wr_deinit(void)
+{
+       fclose(file_out);
+}
+
+static void
+data_read(void)
+{
+       char name[9], desc[90];
+       double lat,lon;
+       char latdir, londir;
+       long alt; 
+       char alttype;
+       char icon[3] = {0};
+       char date[10];
+       char time[9];
+       waypoint *wpt_tmp;
+       char ibuf[100];
+
+       for(;fgets(ibuf, sizeof(ibuf), file_in);) {
+               switch (ibuf[0]) {
+                       case 'W': 
+                       sscanf(ibuf, "W  %s %c%lf %c%lf %s %s %ld %90[^\n']", 
+                               name, &latdir, &lat, &londir, &lon, 
+                               date, time, &alt, desc);
+               wpt_tmp = calloc(sizeof(*wpt_tmp), 1);
+               wpt_tmp->position.altitude.altitude_meters = alt;
+               wpt_tmp->shortname = strdup(name);
+               wpt_tmp->description = strdup(desc);
+
+               if (latdir == 'S') lat = -lat;
+               if (londir == 'W') lon = -lon;
+               wpt_tmp->position.longitude.degrees = lon/100.0;
+               wpt_tmp->position.latitude.degrees = lat/100.0;
+               wpt_tmp->icon_descr = strdup(icon);
+               waypt_add(wpt_tmp);
+               }
+       }
+}
+
+static void
+gpsutil_disp(waypoint *wpt)
+{
+       double lon,lat;
+       signed int ilon, ilat;
+       const char *icon_token = "0";
+       char tbuf[1024];
+       char *tp = tbuf;
+       time_t tm = wpt->creation_time;
+
+       ilon = (signed int)wpt->position.longitude.degrees;
+       ilat = (signed int)wpt->position.latitude.degrees;
+       lon = (ilon * 100.0) + (wpt->position.longitude.degrees - ilon) * 60.0;
+       lat = (ilat * 100.0) + (wpt->position.latitude.degrees - ilat) * 60.0;
+
+       if (tm == 0) 
+               tm = time(NULL);
+       strftime(tbuf, sizeof(tbuf), "%d-%b-%y %I:%M:%S", localtime(&tm));
+       while (*tp) {
+               *tp = toupper(*tp);
+               tp++;
+       }
+
+       fprintf(file_out, "W  %-6.6s %c%08.5f %c%011.5f %s %5d %-40.40s %5e  %s\n",
+               wpt->shortname,
+               lat < 0.0 ? 'S' : 'N',
+               fabs(lat),
+               lon < 0.0 ? 'W' : 'E',
+               fabs(lon),
+               tbuf, 
+               -9999,
+               wpt->description,
+               0.0,
+               icon_token);
+}
+
+static void
+data_write(void)
+{
+fprintf(file_out,
+"H  SOFTWARE NAME & VERSION\n"
+"I  PCX5 2.09\n"
+"\n"
+"H  R DATUM                IDX DA            DF            DX            DY            DZ\n"
+"M  G WGS 84               121 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00\n"
+"\n"
+"H  COORDINATE SYSTEM\n"
+"U  LAT LON DM\n"
+"\n"
+"H  IDNT   LATITUDE    LONGITUDE    DATE      TIME     ALT   DESCRIPTION                              PROXIMITY     SYMBOL ;waypts\n");
+
+       waypt_disp_all(gpsutil_disp);
+}
+
+
+ff_vecs_t pcx_vecs = {
+       rd_init,
+       wr_init,
+       rd_deinit,
+       wr_deinit,
+       data_read,
+       data_write,
+};
diff --git a/gpsbabel/queue.c b/gpsbabel/queue.c
new file mode 100644 (file)
index 0000000..1cb6e6e
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+    Generic queue utilities.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "queue.h"
+
+void
+enqueue(queue *new, queue *old)
+{
+       new->next = old->next;
+       new->prev = old;
+       old->next->prev = new;
+       old->next = new;
+}
+
+queue *
+dequeue(queue *element)
+{
+       queue *prev = element->prev;
+       queue *next = element->next;
+
+       next->prev = prev;
+       prev->next = next;
+       return element;
+}
diff --git a/gpsbabel/queue.h b/gpsbabel/queue.h
new file mode 100644 (file)
index 0000000..84bce2a
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+    Generic queueing utilities.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+typedef struct queue {
+       struct queue *next;
+       struct queue *prev;
+} queue;
+
+void enqueue(queue *new, queue *old);
+queue * dequeue(queue *element);
+
+#define QUEUE_INIT(head) (head)->next = (head)->prev = head
+#define QUEUE_FIRST(head) (head)->next
+#define QUEUE_NEXT(element) (element)->next
+#define QUEUE_LAST(head) (head)->prev
+#define QUEUE_EMPTY (head)->next = head
+
+#define ENQUEUE_TAIL(listhead, element) \
+               enqueue(element, (listhead)->prev)
+
+#define QUEUE_FOR_EACH(listhead, element, tmp) \
+       for ((element) = QUEUE_FIRST(listhead); \
+               (tmp) = QUEUE_NEXT(element), \
+               (element) != (listhead); \
+               (element) = (tmp))
diff --git a/gpsbabel/reference/gl.loc b/gpsbabel/reference/gl.loc
new file mode 100644 (file)
index 0000000..518337c
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0"?><loc version="1.0" src="EasyGPS">
+<waypoint>
+<name id="GCEBB"><![CDATA[Mountain Bike Heaven by susy1313]]></name>
+<coord lat="35.972033" lon="-87.134700"></coord>
+<link text ="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=3771</link>
+</waypoint>
+<waypoint>
+<name id="GC1A37"><![CDATA[The Troll by a182pilot & Family]]></name>
+<coord lat="36.090683" lon="-86.679550"></coord>
+<link text ="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=6711</link>
+</waypoint>
+<waypoint>
+<name id="GC1C2B"><![CDATA[Dive Bomber by JoGPS & family]]></name>
+<coord lat="35.996267" lon="-86.620117"></coord>
+<link text ="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=7211</link>
+</waypoint>
+<waypoint>
+<name id="GC25A9"><![CDATA[FOSTER by JoGPS & Family]]></name>
+<coord lat="36.038483" lon="-86.648617"></coord>
+<link text ="Cache Details">D=9641</link>
+</waypoint>
+<waypoint>
+<name id="GC2723"><![CDATA[Logan Lighthouse by JoGps & Family]]></name>
+<coord lat="36.112183" lon="-86.741767"></coord>
+<link text ="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=10019</link>
+</waypoint>
+<waypoint>
+<name id="GC2B71"><![CDATA[Ganier Cache by Susy1313]]></name>
+<coord lat="36.064083" lon="-86.790517"></coord>
+<link text ="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=11121</link>
+</waypoint>
+<waypoint>
+<name id="GC309F"><![CDATA[Shy's Hill by FireFighterEng33]]></name>
+<coord lat="36.087767" lon="-86.809733"></coord>
+<link text ="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=12447</link>
+</waypoint>
+<waypoint>
+<name id="GC317A"><![CDATA[GittyUp by JoGPS / Warner Parks]]></name>
+<coord lat="36.057500" lon="-86.892000"></coord>
+<link text ="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=12666</link>
+</waypoint>
+<waypoint>
+<name id="GC317D"><![CDATA[Inlighting by JoGPS / Warner Parks]]></name>
+<coord lat="36.082800" lon="-86.867283"></coord>
+<link text ="Cache Details">http://www.geocaching.com/seek/cache_details.asp?ID=12669</link>
+</waypoint>
+</loc>
diff --git a/gpsbabel/reference/gu.wpt b/gpsbabel/reference/gu.wpt
new file mode 100644 (file)
index 0000000..e23f702
--- /dev/null
@@ -0,0 +1,9 @@
+GCEBB    3597.203N 08713.470W 0000000m Mountain Bike Heaven by susy13 a
+GC1A37   3609.068N 08667.955W 0000000m The Troll by a182pilot & Famil a
+GC1C2B   3599.627N 08662.012W 0000000m Dive Bomber by JoGPS & family  a
+GC25A9   3603.848N 08664.862W 0000000m FOSTER by JoGPS & Family       a
+GC2723   3611.218N 08674.177W 0000000m Logan Lighthouse by JoGps & Fa a
+GC2B71   3606.408N 08679.052W 0000000m Ganier Cache by Susy1313       a
+GC309F   3608.777N 08680.973W 0000000m Shy's Hill by FireFighterEng33 a
+GC317A   3605.750N 08689.200W 0000000m GittyUp by JoGPS / Warner Park a
+GC317D   3608.280N 08686.728W 0000000m Inlighting by JoGPS / Warner P a
diff --git a/gpsbabel/route.c b/gpsbabel/route.c
new file mode 100644 (file)
index 0000000..8365348
--- /dev/null
@@ -0,0 +1,47 @@
+/* 
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <stdio.h>
+#include "defs.h"
+
+static queue route_head;
+
+void
+route_init(void)
+{
+       QUEUE_INIT(&route_head);
+}
+
+void
+route_add(waypoint *wpt)
+{
+       ENQUEUE_TAIL(&route_head, &wpt->Q);
+}
+
+void
+route_disp_all(waypt_cb cb)
+{
+       queue *elem, *tmp;
+       waypoint *waypointp;
+
+       QUEUE_FOR_EACH(&route_head, elem, tmp) {
+               waypointp = (waypoint *) elem;
+               (*cb)(waypointp);
+       }
+}
diff --git a/gpsbabel/testo b/gpsbabel/testo
new file mode 100755 (executable)
index 0000000..17f80ee
--- /dev/null
@@ -0,0 +1,45 @@
+PNAME=./gpsbabel
+
+# Geocaching .loc
+${PNAME} -i geo -f geocaching.loc -o geo -F /tmp/gl.loc
+diff /tmp/gl.loc reference
+
+# GPSUtil
+${PNAME} -i geo -f geocaching.loc -o gpsutil -F /tmp/gu.wpt
+diff /tmp/gu.wpt reference
+
+# GPSman 
+${PNAME} -i geo -f geocaching.loc -o gpsman -F /tmp/gm.gm
+${PNAME} -i gpsman -f /tmp/gm.gm -o gpsutil -F /tmp/gm.gm+
+diff /tmp/gm.gm+ /tmp/gu.wpt
+
+# GPX
+${PNAME} -i geo -f geocaching.loc -o gpx -F /tmp/gl.gpx
+${PNAME} -i gpx -f /tmp/gl.gpx -o gpsutil -F /tmp/gpx.gpx
+diff /tmp/gpx.gpx /tmp/gu.wpt
+
+# Magellan Mapsend
+${PNAME} -i geo -f geocaching.loc -o mapsend -F /tmp/mm.mapsend
+${PNAME} -i mapsend -f /tmp/mm.mapsend -o gpsutil -F /tmp/mm.gps
+diff /tmp/mm.gps /tmp/gu.wpt
+
+# Garmin Mapsource
+#${PNAME} -i geo -f geocaching.loc -o mapsource -F /tmp/mm.mapsource
+#${PNAME} -i mapsource -f /tmp/mm.mapsource -o gpsutil -F /tmp/ms.gps
+# diff /tmp/ms.gps /tmp/gu.wpt
+
+# Magellan serial
+# TODO
+
+
+# CSV (Comma separated value) data.
+
+#${PNAME} -i geo -f geocaching.loc -o csv -F /tmp/csv.csv
+#${PNAME} -i csv -f /tmp/csv.csv -o gpsutil -F /tmp/csv2.csv
+#diff /tmp/csv2.csv /tmp/gu.wpt
+
+# PCX (Garmin mapsource import) file format
+${PNAME} -i geo -f geocaching.loc -o pcx -F /tmp/mm.pcx
+${PNAME} -i pcx -f /tmp/mm.pcx -o gpsutil -F /tmp/pcx.gps
+diff /tmp/mm.gps /tmp/gu.wpt
+
diff --git a/gpsbabel/tiger.c b/gpsbabel/tiger.c
new file mode 100644 (file)
index 0000000..da611fc
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+    Access to  U.S. Census Bureau "tiger" format.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include "magellan.h"
+
+static FILE *file_in;
+static FILE *file_out;
+
+static void
+rd_init(const char *fname)
+{
+       file_in = fopen(fname, "r");
+       if (file_in == NULL) {
+               fatal("GPSUTIL: Cannot open %s for reading\n", fname);
+       }
+}
+
+static void
+rd_deinit(void)
+{
+       fclose(file_in);
+}
+
+static void
+wr_init(const char *fname)
+{
+       file_out = fopen(fname, "w");
+       if (file_out == NULL) {
+               fatal("GPSUTIL: Cannot open %s for writing\n", fname);
+       }
+}
+
+static void
+wr_deinit(void)
+{
+       fclose(file_out);
+}
+
+static void
+data_read(void)
+{
+abort();
+#if 0
+       char name[9], desc[30];
+       double lat,lon;
+       char latdir, londir;
+       long alt; 
+       char alttype;
+       char icon[3] = {0};
+       waypoint *wpt_tmp;
+
+       while( fscanf(file_in, "%s %le%c %le%c %ld%c %30[^,] %c",
+                       name, &lat, &latdir, &lon, &londir,
+                       &alt, &alttype, desc, icon) > 0) {
+               wpt_tmp = calloc(sizeof(*wpt_tmp),1);
+               if (wpt_tmp == NULL) {
+                       fatal("GPSMAN: cannot allocate memory\n");
+               }
+               wpt_tmp->position.altitude.altitude_meters = alt;
+               wpt_tmp->shortname = strdup(name);
+               wpt_tmp->description = strdup(desc);
+               wpt_tmp->creation_time = time(NULL);
+
+               if (latdir == 'S') lat = -lat;
+               if (londir == 'W') lon = -lon;
+               wpt_tmp->position.longitude.degrees = lon/100.0;
+               wpt_tmp->position.latitude.degrees = lat/100.0;
+               wpt_tmp->icon_descr = strdup(icon);
+
+               waypt_add(wpt_tmp);
+       }
+#endif
+}
+
+static void
+gpsutil_disp(waypoint *wpt)
+{
+       fprintf(file_out, "%f,%f:redpin:%s\n", 
+               wpt->position.longitude.degrees,
+                wpt->position.latitude.degrees,
+                wpt->description);
+}
+
+static void
+data_write(void)
+{
+       waypt_disp_all(gpsutil_disp);
+}
+
+
+ff_vecs_t tiger_vecs = {
+       rd_init,
+       wr_init,
+       rd_deinit,
+       wr_deinit,
+       data_read,
+       data_write,
+};
diff --git a/gpsbabel/util.c b/gpsbabel/util.c
new file mode 100644 (file)
index 0000000..4433b46
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+    Misc utilities.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+coord
+mkposn(const char *string)
+{
+       coord coord = {0};
+       sscanf(string, "%lf", &coord.degrees);
+       return coord;
+}
+
+void
+printposn(coord *c, int is_lat)
+{
+       char d;
+       if (is_lat) {
+               if (c->degrees < 0) d = 'S'; else d = 'N';
+       } else {
+               if (c->degrees < 0) d = 'W'; else d = 'E';
+       }
+       printf("%lf%c ", fabs(c->degrees), d);
+}
+
+void
+fprintdms(FILE *file, coord *c, int is_lat)
+{
+       char d;
+       if (is_lat) {
+               if (c->degrees < 0) d = 'S'; else d = 'N';
+       } else {
+               if (c->degrees < 0) d = 'W'; else d = 'E';
+       }
+       fprintf(file, "%c%lf\t", d, fabs(c->degrees));
+}
+void
+fatal(const char *fmt, ...)
+{
+       va_list ap;
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       exit(1);
+}
diff --git a/gpsbabel/vecs.c b/gpsbabel/vecs.c
new file mode 100644 (file)
index 0000000..09dbe1d
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+    Describe vectors containing file operations.
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <stdio.h>
+#include "defs.h"
+
+typedef struct {
+       ff_vecs_t *vec;
+       char *name;
+       char *desc;
+} vecs_t;
+
+extern ff_vecs_t geo_vecs;
+extern ff_vecs_t gpsman_vecs;
+extern ff_vecs_t gpx_vecs;
+extern ff_vecs_t mag_vecs;
+extern ff_vecs_t mapsend_vecs;
+extern ff_vecs_t mapsource_vecs;
+extern ff_vecs_t gpsutil_vecs;
+extern ff_vecs_t tiger_vecs;
+extern ff_vecs_t pcx_vecs;
+extern ff_vecs_t csv_vecs;
+
+static
+vecs_t vec_list[] = {
+       {
+               &geo_vecs, 
+               "geo",
+               "Geocaching.com .loc"
+       }, 
+       {
+               &gpsman_vecs,
+               "gpsman",
+               "GPSman"
+       },
+       {
+               &gpx_vecs,
+               "gpx",
+               "GPX XML"
+       },
+       {
+               &mag_vecs,
+               "magellan",
+               "Magellan protocol"
+       },
+       {
+               &mapsend_vecs,
+               "mapsend",
+               "Magellan Mapsend"
+       },
+       {
+               &pcx_vecs,
+               "pcx",
+               "Garmin PCX5"
+       },
+       {
+               &mapsource_vecs,
+               "mapsource",
+               "Garmin Mapsource"
+       },
+       {
+               &gpsutil_vecs,
+               "gpsutil",
+               "gpsutil"
+       },
+       {
+               &tiger_vecs,
+               "tiger",
+               "U.S. Census Bureau Tiger Mapping Service"
+       },
+       {
+               &csv_vecs,
+               "csv",
+               "Comma separated values"
+       },
+       {
+               NULL,
+               NULL,
+               NULL
+       }
+};
+
+ff_vecs_t *
+find_vec(char *const vecname)
+{
+       vecs_t *vec = vec_list;
+       while (vec->vec) {
+               if (strcmp(vecname, vec->name) == 0) {
+                       return vec->vec;
+               }
+               vec++;
+       }
+       return NULL;
+}
+
+void
+disp_vecs(void)
+{
+       vecs_t *vec;
+       for (vec = vec_list; vec->vec; vec++) {
+               printf("%-20.20s  %-50.50s\n",
+                       vec->name, vec->desc);
+       }
+}
diff --git a/gpsbabel/waypt.c b/gpsbabel/waypt.c
new file mode 100644 (file)
index 0000000..20bb03b
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+    Perform various operations on waypoints.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <stdio.h>
+#include "defs.h"
+
+static queue waypt_head;
+static unsigned int waypt_ct;
+
+void
+waypt_init(void)
+{
+       QUEUE_INIT(&waypt_head);
+}
+
+void
+waypt_add(waypoint *wpt)
+{
+       ENQUEUE_TAIL(&waypt_head, &wpt->Q);
+       waypt_ct++;
+}
+
+unsigned int
+waypt_count(void)
+{
+       return waypt_ct;
+}
+
+void
+waypt_disp(waypoint *wpt)
+{
+       if (wpt->creation_time) {
+               printf("%s ", ctime(&wpt->creation_time));
+       }
+       printposn(&wpt->position.latitude,1);
+       printposn(&wpt->position.longitude,0);
+       printf("%s/%s %f\n", 
+               wpt->shortname, 
+               wpt->description, 
+               wpt->position.altitude.altitude_meters);
+}
+
+void
+waypt_disp_all(waypt_cb cb)
+{
+       queue *elem, *tmp;
+       waypoint *waypointp;
+
+       QUEUE_FOR_EACH(&waypt_head, elem, tmp) {
+               waypointp = (waypoint *) elem;
+               (*cb) (waypointp);
+       }
+}